package xyz.esion.blog.config;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import xyz.esion.blog.util.FieldUtil;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Configuration
@RequiredArgsConstructor
public class JacksonConfiguration {

    private final ObjectMapper objectMapper;

    @PostConstruct
    public void registerModule() {
        SimpleModule simpleModule = new SimpleModule();
        // 生成JSON时,将所有Long转换成String
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        // LocalDate、LocalDateTime 序列化 反序列化
        simpleModule.addSerializer(LocalDate.class, new JsonSerializer<LocalDate>() {
            @Override
            public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                gen.writeString(FieldUtil.dateFormat(value));
            }
        });
        simpleModule.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
            @Override
            public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                gen.writeString(FieldUtil.dateFormat(value));
            }
        });
        simpleModule.addDeserializer(LocalDate.class, new JsonDeserializer<LocalDate>() {
            @Override
            public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
                if (StrUtil.isEmpty(jsonParser.getText())) {
                    return null;
                }
                try {
                    return LocalDate.parse(jsonParser.getText(), DateTimeFormatter.ofPattern(FieldUtil.DEFAULT_DATE_PATTERN));
                } catch (Exception e) {
                    throw new IllegalArgumentException(StrUtil.format("参数【{}】，值【{}】格式错误，应为【{}】",
                            jsonParser.getCurrentName(),
                            jsonParser.getText(),
                            FieldUtil.DEFAULT_DATE_PATTERN));
                }
            }
        });
        simpleModule.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
            @Override
            public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
                if (StrUtil.isEmpty(jsonParser.getText())) {
                    return null;
                }
                try {
                    return LocalDateTime.parse(jsonParser.getText(), DateTimeFormatter.ofPattern(FieldUtil.DEFAULT_DATE_TIME_PATTERN));
                } catch (Exception e) {
                    throw new IllegalArgumentException(StrUtil.format("参数【{}】，值【{}】格式错误，应为【{}】",
                            jsonParser.getCurrentName(),
                            jsonParser.getText(),
                            FieldUtil.DEFAULT_DATE_TIME_PATTERN));
                }
            }
        });
        objectMapper.registerModule(simpleModule);
    }

}